#include "src/net/EventLoop.h"
#include "src/net/TimerQueue.h"

#include "gtest/gtest.h"
#include <future>
#include <thread>

using namespace sola;
using namespace sola::net;

TEST(TimerQueueTest, SingleTimer) {
    std::promise<bool> promise;
    auto               future = promise.get_future();

    std::thread t([&]() {
        EventLoop loop; // Create EventLoop inside the thread
        loop.runAfter(0.1, [&]() {
            promise.set_value(true);
            loop.quit();
        });
        loop.loop();
    });

    EXPECT_TRUE(future.get());
    t.join();
}

TEST(TimerQueueTest, RepeatingTimer) {
    EventLoop loop;
    int       count = 0;

    TimerId timerId = loop.runEvery(0.05, [&]() { // 50 milliseconds
        count++;
    });

    // Let it run for ~220ms, it should fire ~4 times
    loop.runAfter(0.22, [&]() {
        loop.cancel(timerId);
        loop.quit();
    });

    loop.loop();

    // Check if it fired approximately the correct number of times
    EXPECT_GE(count, 3);
    EXPECT_LE(count, 5);
}

TEST(TimerQueueTest, CancelTimer) {
    EventLoop loop;
    bool      timerFired = false;

    TimerId timerToCancel = loop.runAfter(0.2, [&]() { timerFired = true; });

    // Schedule cancellation before the timer fires
    loop.runAfter(0.1, [&]() { loop.cancel(timerToCancel); });

    // Schedule a quit event after the original timer was supposed to fire
    loop.runAfter(0.3, [&]() { loop.quit(); });

    loop.loop();

    EXPECT_FALSE(timerFired);
}
